﻿using Kernelx.Contexts.Core;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;


namespace Kernelx.Contexts.AspNetCoreImpls
{
    internal partial class NetCoreWorkloadContext : IWorkloadStartupContext
    {

        private IDictionary<string, object> _dataContainer;
        private readonly ICurrentUser _defaultCurrentUser;
         
        private IServiceProvider _serviceProvider;
        private HttpContext _httpContext;
        private IRequestParameterCollection _requestParameters;
        private Lazy<IEnumerable<FileWrapper>> _fileWrappersLazy;
        private Lazy<ICurrentUser> _currentUserLazy;
        public NetCoreWorkloadContext(ICurrentUser defaultCurrentUser)
        { 
            _dataContainer = new Dictionary<string, object>();
            _defaultCurrentUser = defaultCurrentUser;

            _serviceProvider = null;
            _httpContext = null;
            _requestParameters =null;            
            _fileWrappersLazy = null;
            _currentUserLazy = null;
        }


        public void SetData(string name, object data)
        {
            if (_dataContainer != null)
                _dataContainer[name] = data;
        }

        public object GetData(string name) => _dataContainer != null && _dataContainer.ContainsKey(name) ? _dataContainer[name] : null;

        public void Dispose()
        {
            _dataContainer?.Clear();
            _dataContainer = null;
            _serviceProvider=null;
            _httpContext = null;

            _requestParameters?.Dispose();
            _requestParameters = null;
            _fileWrappersLazy.Disposable();
            _fileWrappersLazy = null;
            _currentUserLazy.Disposable();
            _currentUserLazy = null;
        }

        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(HttpContext))
                return _httpContext;
            return _serviceProvider.GetService(serviceType);
        }


        internal void SetStartupMessage(IServiceProvider serviceProvider, HttpContext httpContext, Func<HttpContext,ICurrentUser> getCurrentUser)
        {
            _serviceProvider = serviceProvider;
            _httpContext = httpContext;

            if (_httpContext != null)
            {
                _requestParameters?.Dispose();
                var request = _httpContext.Request;
                _requestParameters = new HttpRequestParameterCollection(request);
                 
                _fileWrappersLazy = new Lazy<IEnumerable<FileWrapper>>(() => (request.HasFormContentType && request.Form.Files != null) ?
                                request.Form.Files.Select(x => new FileWrapper(x.Name, x.FileName, x.ContentType, x.Length, x.OpenReadStream)).ToList()
                                : new List<FileWrapper>());
            }
             

            _currentUserLazy?.Disposable();
            _currentUserLazy = new Lazy<ICurrentUser>(()=>getCurrentUser(_httpContext)??_defaultCurrentUser); 
        }


        public ICurrentUser User => _currentUserLazy?.Value;

        public IRequestParameterCollection RequestParameters => _requestParameters;

        public IEnumerable<FileWrapper> FileWrappers => _fileWrappersLazy?.Value;
         
    }
}
